package sc;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.OutputStream;
import java.util.Properties;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Configuration extends JDialog implements ActionListener, ChangeListener
{
	private static final long serialVersionUID = 1L;
	private static Configuration instance;
	private static final String PROPERTIES_FILE = Harlequin.BASE_PATH + "/harlequin.properties";
	public static Image icon = Images.getImage("/images/configuration.png");
    private static Image bckg = Images.getImage("/images/configbg.jpg");
	public static Properties properties = new Properties();

	private JSlider updaterate;
	private JLabel downloadestimate;
	private JCheckBox forumarrivals;
	private JCheckBox forumexits;
	private JCheckBox chatarrivals;
	private JCheckBox chatexits;
	private JCheckBox ventarrivals;
	private JCheckBox ventexits;
	private JCheckBox startupmemberslist;
    
    public class ImagePanel extends JPanel
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void paintComponent(Graphics g)
        {
            if (Configuration.bckg != null)
                g.drawImage(Configuration.bckg, 0, 0, this);
        }
    }
    
	public static void initialise()
	{
		try
		{
			FileReader reader = new FileReader(PROPERTIES_FILE);
			properties.load(reader);
			defaultProperties();
		}
		catch(Exception e)
		{
			defaultProperties();
			saveConfiguration();
		}
	}
	
	public static Configuration open()
	{
		if (instance == null)
			instance = new Configuration();
		Point p = Harlequin.getInstance().getLocation();
		p.move(p.x + 10, p.y + 52);
		instance.setLocation(p);
		instance.setVisible(true);
		instance.setAlwaysOnTop(true);
		return instance;
	}
	
	private Configuration()
	{
		setIconImage(icon);
		setTitle("Configuration");
		setResizable(false);
		
		FlowLayout leftjustify = new FlowLayout(FlowLayout.LEFT);
		FlowLayout rightjustify = new FlowLayout(FlowLayout.RIGHT);
		Dimension labelsSize = new Dimension(100, 73);
		Dimension smalllabelsSize = new Dimension(100, 25);
				
		JPanel controls = new JPanel();
		controls.setOpaque(false);
		controls.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridx = 0;
		
		// Update rate
		JPanel subpanel = new JPanel(leftjustify);
		subpanel.setOpaque(false);
		JPanel inset = new JPanel(rightjustify);
		inset.setOpaque(false);
		inset.setPreferredSize(labelsSize);
		JLabel label = new JLabel("Update interval (s):");
		inset.add(label);
		int initialvalue = Integer.parseInt(properties.getProperty("harlequin.sysbox.updaterate"))/1000;
		int estimate = (int)(0.00193f * (60f / initialvalue) * 60 * 24 * 30);
		downloadestimate = new JLabel("(~" + estimate + " MB/month)");
		inset.add(downloadestimate);
		subpanel.add(inset);
		inset = new JPanel();
		inset.setOpaque(false);
		updaterate = new JSlider(JSlider.HORIZONTAL, 5, 60, initialvalue);
		updaterate.setMajorTickSpacing(55);
		updaterate.setMinorTickSpacing(5);
		updaterate.setPaintTicks(true);
		updaterate.setPaintLabels(true);
		updaterate.setSnapToTicks(true);
		updaterate.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
			    if (!updaterate.getValueIsAdjusting()) {
			        int value = (int)updaterate.getValue();
			        int estimate = (int)(0.00193f * (60f / value) * 60 * 24 * 30);
			        downloadestimate.setText("(~" + estimate + " MB/month)");
			    }
			}
		});
		updaterate.setOpaque(false);
		inset.add(updaterate);
		subpanel.add(inset);
		controls.add(subpanel, c);
		
		// Event notifications
		subpanel = new JPanel(leftjustify);
		subpanel.setOpaque(false);
		inset = new JPanel(rightjustify);
		inset.setOpaque(false);
		inset.setPreferredSize(labelsSize);
		label = new JLabel("Notify on:");
		inset.add(label);
		subpanel.add(inset);
		inset = new JPanel();
		inset.setOpaque(false);
		inset.setLayout(new GridLayout(0,2));
		forumarrivals = new JCheckBox("Forum arrivals");
		forumarrivals.setOpaque(false);
		forumarrivals.setSelected(notifyForumArrivals());
		inset.add(forumarrivals);
		forumexits = new JCheckBox("Forum exits");
		forumexits.setOpaque(false);
		forumexits.setSelected(notifyForumExits());
		inset.add(forumexits);
		chatarrivals = new JCheckBox("Chat arrivals");
		chatarrivals.setOpaque(false);
		chatarrivals.setSelected(notifyChatArrivals());
		inset.add(chatarrivals);
		chatexits = new JCheckBox("Chat exits");
		chatexits.setOpaque(false);
		chatexits.setSelected(notifyChatExits());
		inset.add(chatexits);
		ventarrivals = new JCheckBox("Vent arrivals");
		ventarrivals.setOpaque(false);
		ventarrivals.setSelected(notifyVentArrivals());
		inset.add(ventarrivals);
		ventexits = new JCheckBox("Vent exits");
		ventexits.setOpaque(false);
		ventexits.setSelected(notifyVentExits());
		inset.add(ventexits);
		subpanel.add(inset);
		controls.add(subpanel, c);

		// Startup options
		subpanel = new JPanel(leftjustify);
		subpanel.setOpaque(false);
		inset = new JPanel(rightjustify);
		inset.setOpaque(false);
		inset.setPreferredSize(smalllabelsSize);
		label = new JLabel("On startup:");
		inset.add(label);
		subpanel.add(inset);
		inset = new JPanel();
		inset.setOpaque(false);
		inset.setLayout(new GridLayout(0,2));
		startupmemberslist = new JCheckBox("Show members list");
		startupmemberslist.setOpaque(false);
		startupmemberslist.setSelected(startupMembersList());
		inset.add(startupmemberslist);
		subpanel.add(inset);
		controls.add(subpanel, c);
		
		// OK/Cancel buttons
		subpanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        subpanel.setOpaque(false);
		JButton button = new JButton("  OK  ");
		button.addActionListener(this);
		subpanel.add(button);
		button = new JButton("Cancel");
		button.addActionListener(this);
		subpanel.add(button);
		
		JPanel panel = new ImagePanel();
		panel.setLayout(new BorderLayout());
		panel.add(controls, BorderLayout.CENTER);
		panel.add(subpanel, BorderLayout.SOUTH);
		getContentPane().add(panel);
		
		pack();
	}

	public void actionPerformed(ActionEvent e)
	{
		String cmd = e.getActionCommand();
		
		if (cmd == "  OK  ")
		{
			updateProperties();
			saveConfiguration();
			setVisible(false);
		}
		else if (cmd == "Cancel")
		{
			updaterate.setValue(Integer.parseInt(properties.getProperty("harlequin.sysbox.updaterate"))/1000);
			forumarrivals.setSelected(notifyForumArrivals());
			forumexits.setSelected(notifyForumExits());
			chatarrivals.setSelected(notifyChatArrivals());
			chatexits.setSelected(notifyChatExits());
			ventarrivals.setSelected(notifyVentArrivals());
			ventexits.setSelected(notifyVentExits());
			startupmemberslist.setSelected(startupMembersList());
			setVisible(false);
		}
	}

	public void stateChanged(ChangeEvent e)
	{
		
	}
	
	public static boolean notifyForumArrivals()
	{
		return properties.getProperty("harlequin.sysbox.notifyforumarrivals").equals("true");
	}
	
	public static boolean notifyForumExits()
	{
		return properties.getProperty("harlequin.sysbox.notifyforumexits").equals("true");
	}
	
	public static boolean notifyChatArrivals()
	{
		return properties.getProperty("harlequin.sysbox.notifychatarrivals").equals("true");
	}
	
	public static boolean notifyChatExits()
	{
		return properties.getProperty("harlequin.sysbox.notifychatexits").equals("true");
	}
	
	public static boolean notifyVentArrivals()
	{
		return properties.getProperty("harlequin.sysbox.notifyventarrivals").equals("true");
	}
	
	public static boolean notifyVentExits()
	{
		return properties.getProperty("harlequin.sysbox.notifyventexits").equals("true");
	}
	
	public static int updateRate()
	{
		return Integer.parseInt(properties.getProperty("harlequin.sysbox.updaterate"));
	}
	
	public static boolean startupMembersList()
	{
		return properties.getProperty("harlequin.sysbox.startupMembersList").equals("true");
	}
	
	public static int autoLaunchTime()
	{
		return Integer.parseInt(properties.getProperty("harlequin.sysbox.autolaunchtime"));
	}

	private void updateProperties()
	{
		properties.setProperty("harlequin.sysbox.updaterate", Integer.toString(updaterate.getValue() * 1000));
		properties.setProperty("harlequin.sysbox.notifyforumarrivals", Boolean.toString(forumarrivals.isSelected()));
		properties.setProperty("harlequin.sysbox.notifyforumexits", Boolean.toString(forumexits.isSelected()));
		properties.setProperty("harlequin.sysbox.notifychatarrivals", Boolean.toString(chatarrivals.isSelected()));
		properties.setProperty("harlequin.sysbox.notifychatexits", Boolean.toString(chatexits.isSelected()));
		properties.setProperty("harlequin.sysbox.notifyventarrivals", Boolean.toString(ventarrivals.isSelected()));
		properties.setProperty("harlequin.sysbox.notifyventexits", Boolean.toString(ventexits.isSelected()));
		properties.setProperty("harlequin.sysbox.startupMembersList", Boolean.toString(startupmemberslist.isSelected()));
	}
	
	private static void saveConfiguration()
	{
		try
		{
			OutputStream outfile = new FileOutputStream(PROPERTIES_FILE);
			properties.store(outfile, "This is the properties file for the Harlequin client");
		}
		catch(Exception e){}
	}
	
	private static void defaultProperties()
	{
		if (properties.getProperty("handlers") == null)
			properties.setProperty("handlers", "java.util.logging.FileHandler");
		if (properties.getProperty(".level") == null)
			properties.setProperty(".level", "ALL");
		if (properties.getProperty("java.util.logging.FileHandler.level") == null)
			properties.setProperty("java.util.logging.FileHandler.level", "INFO");
		if (properties.getProperty("java.util.logging.FileHandler.pattern") == null)
			properties.setProperty("java.util.logging.FileHandler.pattern", "%h/Harlequin/harlequin.log");
		if (properties.getProperty("java.util.logging.FileHandler.limit") == null)
			properties.setProperty("java.util.logging.FileHandler.limit", "1000000");
		if (properties.getProperty("java.util.logging.FileHandler.count") == null)
			properties.setProperty("java.util.logging.FileHandler.count", "1");
		if (properties.getProperty("java.util.logging.FileHandler.formatter") == null)
			properties.setProperty("java.util.logging.FileHandler.formatter", "sc.Log");
		if (properties.getProperty("harlequin.sysbox.updaterate") == null)
			properties.setProperty("harlequin.sysbox.updaterate", "20000");
		if (properties.getProperty("harlequin.sysbox.notifyforumarrivals") == null)
			properties.setProperty("harlequin.sysbox.notifyforumarrivals", "true");
		if (properties.getProperty("harlequin.sysbox.notifyforumexits") == null)
			properties.setProperty("harlequin.sysbox.notifyforumexits", "true");
		if (properties.getProperty("harlequin.sysbox.notifychatarrivals") == null)
			properties.setProperty("harlequin.sysbox.notifychatarrivals", "true");
		if (properties.getProperty("harlequin.sysbox.notifychatexits") == null)
			properties.setProperty("harlequin.sysbox.notifychatexits", "true");
		if (properties.getProperty("harlequin.sysbox.notifyventarrivals") == null)
			properties.setProperty("harlequin.sysbox.notifyventarrivals", "true");
		if (properties.getProperty("harlequin.sysbox.notifyventexits") == null)
			properties.setProperty("harlequin.sysbox.notifyventexits", "true");
		if (properties.getProperty("harlequin.sysbox.startupMembersList") == null)
			properties.setProperty("harlequin.sysbox.startupMembersList", "false");
		if (properties.getProperty("harlequin.sysbox.autolaunchtime") == null)
			properties.setProperty("harlequin.sysbox.autolaunchtime", "0");
	}
	
}
